package com.tanhua.dubbo.api;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.tanhua.model.enums.CommentSubject;
import com.tanhua.model.enums.CommentType;
import com.tanhua.model.mongo.Comment;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.mongo.Video;
import com.tanhua.model.vo.PageResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.Collections;
import java.util.List;

/**
 * @author Xiao
 * @date 2021/10/28
 */
@DubboService
@Slf4j
public class CommentApiImpl implements CommentApi{
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private MovementApi movementApi;

    @Override
    public List<Comment> selectByMovementId(String publishId, CommentType commentType, Integer page, Integer pagesize) {
        Criteria criteria = Criteria
                .where("publishId").is(new ObjectId(publishId))
                .and("commentType").is(commentType.getType());
        Long skip = Long.valueOf((page - 1) * pagesize);
        Query query = Query.query(criteria)
                .skip(skip)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        List<Comment> comments = mongoTemplate.find(query, Comment.class);
        for (Comment comment : comments) {
            log.info(comment.toString());
        }
        return comments;
    }

    @Override
    public Boolean hasComment(Long userId, String movementId, CommentType commentType) {
        Criteria criteria = Criteria
                .where("publishId").is(new ObjectId(movementId))
                .and("userId").is(userId)
                .and("commentType").is(commentType.getType());
        Query query = Query.query(criteria);
        //判断数据是否存在：mongoTemplate.exists()
        return mongoTemplate.exists(query, Comment.class);
    }

    @Override
    public Integer save(Comment comment, CommentSubject commentSubject) {
        Long publishUserId = null;
        switch (commentSubject) {
            case MOVEMENT:{
                //查询动态信息
                Movement movement = mongoTemplate.findById(comment.getPublishId(), Movement.class);
                if (ObjectUtil.isNotEmpty(movement)) {
                    publishUserId = movement.getUserId();
                }
                break;
            }
            case COMMENT:{
                Comment parentComment = mongoTemplate.findById(comment.getPublishId(), Comment.class);
                if (ObjectUtil.isNotEmpty(parentComment)) {
                    publishUserId = parentComment.getUserId();
                }
                break;
            }
            case VIDEO:{
                Video video = mongoTemplate.findById(comment.getPublishId(), Video.class);
                if (ObjectUtil.isNotEmpty(video)) {
                    publishUserId = video.getUserId();
                }
                break;
            }
            default:
                break;
        }
        //设置Comment的发布用户id
        comment.setPublishUserId(publishUserId);
        //添加评论数据
        mongoTemplate.save(comment);
        //更新并保存动态数据、返回最新结果
        Integer changeNum = 1;
        return getCount(comment, commentSubject, changeNum);
    }

    @Override
    public Integer delete(Comment comment, CommentSubject commentSubject) {
        //删除当前用户的点赞/喜欢数据
        Criteria criteria = Criteria.where("publishId").is(comment.getPublishId())
                .and("commentType").is(comment.getCommentType())
                .and("userId").is(comment.getUserId());
        mongoTemplate.remove(Query.query(criteria), Comment.class);
        //更新动态表对应的点赞/喜欢数据、返回最新结果
        Integer change = -1;
        return getCount(comment, commentSubject, change);
    }

    /**
     * 更新动态表中对应的评论、点赞、喜欢数量并返回最新数量
     * @param comment   封装了评论查询条件
     * @param commentSubject    评论类型枚举对象
     * @param changeNum 添加为1，删除为-1
     * @return
     */
    private Integer getCount(Comment comment, CommentSubject commentSubject, Integer changeNum) {
        //更新动态数据的点赞、评论、喜欢对应的字段
        Query query = Query.query(Criteria.where("id").is(comment.getPublishId()));
        Update update = new Update();
        Integer commentType = comment.getCommentType();
        if (commentType.equals(CommentType.LIKE.getType())) {
            update.inc("likeCount", changeNum);
        } else if (commentType.equals(CommentType.COMMENT.getType())) {
            update.inc("commentCount", changeNum);
        } else {
            update.inc("loveCount", changeNum);
        }
        //设置更新参数
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.returnNew(true);    //true--获取更新后的数据
        //获取最新的对应字段数量并返回
        Integer count = null;
        switch (commentSubject) {
            case MOVEMENT: {
                Movement movementModify = mongoTemplate.findAndModify(query, update, options, Movement.class);
                count = movementModify.statisCount(commentType);
                break;
            }
            case COMMENT: {
                Comment commentResult = mongoTemplate.findAndModify(query, update, options, Comment.class);
                count = commentResult.getLikeCount();
                break;
            }
            case VIDEO: {
                Video videoResult = mongoTemplate.findAndModify(query, update, options, Video.class);
                count = videoResult.statisCount(comment.getCommentType());
                break;
            }
            default:
                break;
        }
        return count;
    }

    @Override
    public PageResult getComments(Integer page, Integer pagesize, String messageID) {
        Criteria criteria = Criteria.where("publishId").is(new ObjectId(messageID)).and("commentType").is(CommentType.COMMENT.getType());
        Long count = mongoTemplate.count(Query.query(criteria), Comment.class);
        Long skip = (long) (page - 1) * pagesize;
        Query query = Query.query(criteria)
                .skip(skip)
                .limit(pagesize)
                .with(Sort.by(Sort.Order.desc("created")));
        List<Comment> comments = mongoTemplate.find(query, Comment.class);
        if (CollUtil.isEmpty(comments)) {
            return new PageResult();
        }
        return new PageResult(page, pagesize, Integer.parseInt(count.toString()), comments);
    }
}
